package gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;

import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import model.Console;
import model.Game;
import configuration.RomLoader;

public class EmulatorGUI extends JPanel implements ListSelectionListener {
	
	private static final long serialVersionUID = 1L;
	private JList<Game> gameList;
	private DefaultListModel<Game> listModel;

	private JTextArea log;
	static private String newline = "\n";

	public EmulatorGUI() {
		super(new BorderLayout());

		// Create and populate the gameList model.
        final JPanel buttonPane = new JPanel();

        listModel = new DefaultListModel<Game>();
        for(Console console:RomLoader.getConsoles()){
            // Create the gameList-modifying buttons.
        	final ImageIcon image = createImageIcon(console.getIco());
            final JButton addButton = new JButton(console.getName(),image);
            addButton.setActionCommand(console.getName());
            addButton.addActionListener(new SelectButtonListener());
            addButton.setSize(50,50);
            buttonPane.add(addButton);

            add(buttonPane, BorderLayout.AFTER_LAST_LINE);
            for(Game game:console.getGames()){
                listModel.addElement(game);
            }

        }

        final JButton addButtonAll = new JButton("All");
        addButtonAll.setActionCommand("All");
        addButtonAll.addActionListener(new SelectButtonListener());
        buttonPane.add(addButtonAll);

		listModel.addListDataListener(new MyListDataListener());

		// Create the gameList and put it in a scroll pane.
		gameList = new JList<Game>(listModel);
		gameList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		gameList.setSelectedIndex(0);
		gameList.addListSelectionListener(this);
		JScrollPane listScrollPane = new JScrollPane(gameList);

        MouseListener mouseListener = new MouseAdapter() {
            public void mouseClicked(MouseEvent mouseEvent) {
                @SuppressWarnings("unchecked")
				JList<Game> theList = (JList<Game>) mouseEvent.getSource();
                if (mouseEvent.getClickCount() == 1) {
                    int index = theList.locationToIndex(mouseEvent.getPoint());
                    if (index >= 0) {
                        Game game = (Game)theList.getModel().getElementAt(index);
                        System.out.println("1-clicked on: " +game.toString());
                        log.append("1-clicked on: " + game.toString() + newline);
                        log.setCaretPosition(log.getDocument().getLength());
                        try {
                            new ProcessBuilder("xterm", "-e","fceux " + game.getPath()).start();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }
                }
            }
        };
        gameList.addMouseListener(mouseListener);
		// Create the log for reporting gameList data events.
		log = new JTextArea(10, 20);
		JScrollPane logScrollPane = new JScrollPane(log);
		// Create a split pane for the log and the gameList.
		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,listScrollPane, logScrollPane);
		splitPane.setResizeWeight(0.5);
		// Put everything together.
		add(splitPane, BorderLayout.CENTER);
	}

	class MyListDataListener implements ListDataListener {
		public void contentsChanged(ListDataEvent e) {
			log.append("contentsChanged: " + e.getIndex0() + ", "
					+ e.getIndex1() + newline);
			log.setCaretPosition(log.getDocument().getLength());
		}

		public void intervalAdded(ListDataEvent e) {
			log.append("intervalAdded: " + e.getIndex0() + ", " + e.getIndex1()
					+ newline);
			log.setCaretPosition(log.getDocument().getLength());
		}

		public void intervalRemoved(ListDataEvent e) {
			log.append("intervalRemoved: " + e.getIndex0() + ", "
					+ e.getIndex1() + newline);
			log.setCaretPosition(log.getDocument().getLength());
		}
	}


	/** A listener shared by the text field and add button. */
	class SelectButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
            System.out.println(e.getActionCommand());
			gameList.setSelectedIndex(0);
            listModel.clear();
            final Collection<Console> consoles = RomLoader.getConsoles(e.getActionCommand());
            if(e.getActionCommand().equals("All")){
                consoles.clear();
                consoles.addAll(RomLoader.getConsoles());
            }
            for(Console console:consoles){
                for(Game game:console.getGames()){
                    listModel.addElement(game);
                }
            }

		}
	}

	// Listener method for gameList selection changes.
	public void valueChanged(ListSelectionEvent e) {
		if (e.getValueIsAdjusting() == false) {

		}
	}

	
	/** Returns an ImageIcon, or null if the path was invalid. 
	 * @throws MalformedURLException */
	protected static ImageIcon createImageIcon(String imageName){
		java.net.URL imageURL=null;
		try {
			imageURL = new URL("file://" + imageName);
			final ImageIcon image = new ImageIcon(imageURL);
			return image;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} 
		return null;
		
	}

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event-dispatching thread.
	 */
	private static void createAndShowGUI() {
		// Create and set up the window.
		JFrame frame = new JFrame("Megajandro | Emulator Chase");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// Create and set up the content pane.
		JComponent newContentPane = new EmulatorGUI();
		newContentPane.setOpaque(true); // content panes must be opaque
		frame.setContentPane(newContentPane);

		// Don't let the content pane get too small.
		// (Works if the Java look and feel provides
		// the window decorations.)
		newContentPane.setMinimumSize(new Dimension(newContentPane
				.getPreferredSize().width, 100));

		// Display the window.
		frame.pack();
		frame.setVisible(true);
	}

	public static void main(String[] args) {
        RomLoader.load();
        RomLoader.printConsole();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}
}
